<template>
  <div>
    <el-row>
      <el-col :xs="1" :lg="1"></el-col>
      <el-col :xs="22" :lg="22">
        <el-tabs
          style="max-height: 900px; overflow-y: auto; width: 105%"
          type="border-card"
          tabPosition="left"
          ><el-tab-pane label="用户数据"
            ><el-card body-style="display: flex;flex-direction: column;">
              <div class="container">
                <div class="charts" ref="category"></div>
                <div class="middle" ref="liquid"></div>
                <div class="right" ref="bar"></div>
              </div>
              <div class="line" ref="line"></div>
              <div class="table-container"></div>
            </el-card>
          </el-tab-pane>
          <el-tab-pane label="用户管理">
            <el-card style="height: 80px">
              <el-form :inline="true" class="form">
                <el-form-item label="用户名:">
                  <el-input
                    placeholder="请你输入搜索用户名"
                    v-model="keyword"
                  ></el-input>
                </el-form-item>
                <el-form-item>
                  <el-button
                    type="primary"
                    size="default"
                    :disabled="keyword ? false : true"
                    @click="search"
                    >搜索</el-button
                  >
                  <el-button type="primary" size="default" @click="reset"
                    >重置</el-button
                  >
                </el-form-item>
              </el-form>
            </el-card>
            <el-card style="margin-top: 20px">
              <el-button type="primary" size="default" @click="addUser"
                >添加用户</el-button
              >
              <el-button
                type="danger"
                size="default"
                @click="deleteSelectUser"
                plain
                >批量删除</el-button
              >
              <el-table
                :data="tableData"
                border
                stripe
                style="margin: 10px 0px; width: 100%"
                max-height="700"
                @selection-change="handleSelectionChange"
                table-layout="auto"
              >
                <el-table-column type="selection" align="center" width="50" />
                <el-table-column
                  prop="ID"
                  label="ID"
                  width="80"
                  align="center"
                  sortable
                />
                <el-table-column
                  prop="username"
                  label="用户名"
                  width="200"
                  align="center"
                />
                <el-table-column
                  prop="age"
                  label="年龄"
                  width="100"
                  align="center"
                />
                <el-table-column
                  prop="gender"
                  label="性别"
                  width="100"
                  align="center"
                  show-overflow-tooltip="true"
                >
                </el-table-column>
                <el-table-column
                  prop="sign_at"
                  label="注册时间"
                  width="250"
                  align="center"
                />

                <el-table-column
                  prop="login_at"
                  label="最近登录时间"
                  width="250"
                  align="center"
                />
                <el-table-column
                  prop="job"
                  label="职业"
                  width="150"
                  align="center"
                />
                <el-table-column
                  prop="role"
                  label="角色"
                  width="150"
                  align="center"
                />
                <el-table-column
                  prop="operation"
                  label="操作"
                  width="250"
                  align="center"
                  style="overflow: hidden"
                >
                  <template #="{ row }">
                    <el-button
                      type="primary"
                      size="small"
                      icon="Edit"
                      @click="updateUser(row)"
                      >编辑</el-button
                    >
                    <el-popconfirm
                      :title="`你确定要删除${row.username}?`"
                      width="260px"
                      @confirm="deleteUser(row.ID)"
                    >
                      <template #reference>
                        <el-button type="danger" size="small" icon="Delete"
                          >删除</el-button
                        >
                      </template>
                    </el-popconfirm>
                  </template>
                </el-table-column>
              </el-table>
              <el-pagination
                style="margin-top: 15px"
                v-model:current-page="currentPage"
                v-model:page-size="pageSize"
                :page-sizes="[5, 7, 10, 12, 20]"
                layout="prev, pager, next, jumper,->,sizes,total"
                :total="total"
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
              />
            </el-card>
          </el-tab-pane>
        </el-tabs>
      </el-col>
      <el-col :xs="1" :lg="1"></el-col>
    </el-row>
    <el-row></el-row>
  </div>
  <el-dialog v-model="isCreate" :title="title" width="40%" center>
    <el-form
      :model="newUser"
      label-width="100px"
      :label-position="left"
      style="width: 80%; margin-left: 20%"
    >
      <el-form-item label="用户名">
        <el-input
          v-model="newUser.username"
          placeholder="请输入用户名"
          style="width: 240px"
        />
      </el-form-item>
      <el-form-item label="密码">
        <el-input
          v-model="newUser.password"
          placeholder="请输入用户密码"
          type="password"
          style="width: 240px"
          show-password
        />
      </el-form-item>
      <el-form-item label="权限">
        <el-select
          v-model="newUser.role"
          clearable
          placeholder="选择用户权限"
          style="width: 240px"
        >
          <el-option
            v-for="item in roleList"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="cancel">取消</el-button>
        <el-button type="primary" @click="handleCreateOrEdit"> 确定 </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
import { onMounted, ref } from "vue";
import {
  reqGetAge,
  reqGetLoginSign,
  reqGetGender,
  reqGetAllUser,
  reqDeleteUser,
  reqSign,
  reqDeleteUsers,
  reqUpdateInfo,
} from "@/api/user";
import * as echarts from "echarts";
import "echarts-liquidfill";
import { ElMessage } from "element-plus";
const category = ref();
const liquid = ref();
const bar = ref();
const line = ref();
const Xdata = ref([]);
const Ydata = ref([]);
const liquidData = ref();
const genderData = ref();
const lineData = ref({
  xdata: [],
  ydata: [],
});
const tableData = ref([]);
const currentPage = ref(1);
const pageSize = ref(7);
const total = ref();
const keyword = ref("");
const newUser = ref({});
const isCreate = ref(false);
const roleList = [
  { value: "admin", label: "管理员" },
  { value: "user", label: "普通用户" },
];
const idList = ref([]);
const editUser = ref({});
const title = ref("");
const editID = ref();
onMounted(async () => {
  await getAgeData();
  await getLoginSign();
  await getGenderData();
  await initEchart();
  await initLiquid();
  await initBar();
  await initLine();
  await getAllUser();
});
const updateUser = (row) => {
  isCreate.value = true;
  title.value = "编辑用户";
  console.log(row);
  newUser.value.username = row.username;
  newUser.value.password = row.password;
  editID.value = row.ID;
  newUser.value.role = row.role;
};
const handleSelectionChange = (val) => {
  let list = [];
  console.log(val);
  val.forEach((item) => {
    list.push(item.ID);
  });
  idList.value = list;
};
const addUser = () => {
  isCreate.value = true;
  title.value = "创建用户";
};
const cancel = () => {
  isCreate.value = false;
  newUser.value = {};
};
const deleteSelectUser = async () => {
  try {
    await reqDeleteUsers({ id_list: idList.value });
    await getAllUser();
    ElMessage.success("删除成功！");
  } catch {
    ElMessage.error("删除失败！");
  }
};
const handleCreateOrEdit = async () => {
  if (title.value == "编辑用户") {
    try {
      await reqUpdateInfo(editID.value, newUser.value);
      await getAllUser();
      ElMessage.success("编辑成功！");
    } catch (e) {
      ElMessage.error("编辑失败！");
    }
  } else {
    try {
      await reqSign(newUser.value);
      await getAllUser();
      ElMessage.success("创建用户成功！");
    } catch (e) {
      ElMessage.error("创建用户失败！");
    }
  }
  newUser.value = {};
  isCreate.value = false;
};
const deleteUser = async (id) => {
  try {
    await reqDeleteUser(id);
    ElMessage.success("删除成功!");
    await getAllUser();
  } catch (e) {
    ElMessage.error("删除失败!");
  }
};
const handleSizeChange = async () => {
  await getAllUser();
};
const handleCurrentChange = async () => {
  await getAllUser();
};
const search = () => {
  getAllUser();
};
const reset = () => {
  keyword.value = "";
  getAllUser();
};
const getAllUser = async () => {
  let res = await reqGetAllUser({
    page: currentPage.value,
    size: pageSize.value,
    name: keyword.value,
  });
  res.data.forEach((item) => {
    item.gender = item.gender == 0 ? "女" : "男";
    item.role = item.role == "user" ? "普通用户" : "管理员";
  });
  tableData.value = res.data;
  total.value = res.total;
};
const getAgeData = async () => {
  let res = await reqGetAge();
  Xdata.value = res.data.names;
  Ydata.value = res.data.values;
};
const getLoginSign = async () => {
  let res = await reqGetLoginSign();
  liquidData.value = (res.data.login.value / res.data.login.total).toFixed(4);
  res.data.sign.forEach((item) => {
    lineData.value.xdata.push(item.name);
    lineData.value.ydata.push(item.value);
  });
  console.log(liquidData.value);
};
const getGenderData = async () => {
  let res = await reqGetGender();
  genderData.value = res.data;
};
const initEchart = () => {
  const myChart = echarts.init(category.value);
  let option = {
    title: {
      text: "用户年龄分布",
      textStyle: {
        color: "#7e9fb6",
      },
      left: "center",
    },
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "shadow",
      },
    },
    grid: {
      top: "15%",
      left: "10%",
      bottom: "12%",
    },
    xAxis: [
      {
        name: "岁",
        type: "category",
        data: Xdata.value,
        axisLine: {
          lineStyle: {
            color: "#7e9fb6",
          },
          symbol: ["none", "arrow"],
        },
        axisTick: {
          show: false,
        },
        axisLabel: {
          margin: 5,
          color: "#7e9fb6",
          textStyle: {
            fontSize: 12,
          },
        },
      },
    ],
    yAxis: [
      {
        name: "个",
        axisLabel: {
          color: "#7e9fb6",
        },
        axisLine: {
          show: true,
          lineStyle: {
            color: "#7e9fb6",
          },
          symbol: ["none", "arrow"],
        },

        splitLine: {
          lineStyle: {
            color: "rgba(126,159,182,0.12)",
          },
        },
      },
    ],
    series: [
      {
        type: "bar",
        name: "用户数量",
        data: Ydata.value,
        barWidth: "20px",
        itemStyle: {
          color: "#6EC3C9",
        },
      },
    ],
  };
  myChart.setOption(option);
};
const initLiquid = () => {
  const myChart = echarts.init(liquid.value);
  let option = {
    title: {
      text: "当月活跃用户",
      textStyle: {
        fontSize: 20,
      },
      left: "center",
      bottom: "20%",
    },
    series: [
      {
        top: "-50%",
        name: "活跃率",
        type: "liquidFill",
        color: ["#1082FF", "rgba(16, 130, 255, 0.5)"],
        data: [liquidData.value],
        // center: ["25%", "50%"],
        radius: "40%",
        outline: {
          itemStyle: {
            borderWidth: 4,
            borderColor: "#1082FF",
          },
        },
        backgroundStyle: {
          color: "#fff",
        },
        itemStyle: {
          opacity: 0.95,
          shadowColor: "rgba(0, 0, 0, 0)",
        },
        label: {
          formatter: function (p) {
            return `{b|${parseFloat((p.value * 100).toFixed(2))}}%\n{a|${
              p.seriesName
            }}`;
          },
          rich: {
            a: {
              fontSize: 14,
            },
          },
          position: ["50%", "50%"],
          fontSize: 28,
          fontWeight: 700,
          fontFamily: "SourceHanSansCN",
          color: "#1082FF",
        },
      },
    ],
  };
  myChart.setOption(option);
};
const initBar = () => {
  var female =
    "";
  var male =
    "";

  let maleValue = genderData.value.male;
  let femaleValue = genderData.value.female;

  let total = maleValue + femaleValue;
  let malePercent = maleValue / total;
  let femalePercent = femaleValue / total;
  const mycharts = echarts.init(bar.value);
  let option = {
    xAxis: {
      type: "value",
      show: false,
    },
    yAxis: [
      {
        type: "category",
        inverse: true,
        data: ["男生"],
        axisTick: {
          show: false,
        },
        axisLine: {
          show: false,
        },
        axisLabel: {
          show: false,
        },
      },
      {
        type: "category",
        inverse: true,
        data: ["女生"],
        axisTick: {
          show: false,
        },
        axisLine: {
          show: false,
        },
        axisLabel: {
          show: false,
        },
      },
    ],
    series: [
      {
        type: "bar",
        barWidth: 20,
        data: [malePercent],
        z: 20,
        itemStyle: {
          normal: {
            barBorderRadius: 10,
            color: "#3E6DFF",
          },
        },
      },
      {
        type: "bar",
        barWidth: 20,
        data: [0],
        barGap: "-100%",
        itemStyle: {
          normal: {
            barBorderRadius: 10,
            color: "rgba(0,0,0,0)",
          },
        },
        markPoint: {
          symbol: "rect",
          // x:'0%',
          symbolSize: [45, 122],
          symbolOffset: [-35, 0],
          label: {
            color: "rgba(0,0,0,0)",
            formatter: (params) => {
              console.log("params", params);
              return `{value|${(malePercent * 100).toFixed(
                2
              )}%}\n\n\n\n\n\n\n{name|${params.name}}`;
            },
            rich: {
              value: {
                color: "rgba(0, 252, 253, 1)",
                fontSize: 20,
                padding: [0, 0, 0, 150],
                fontWeight: "bold",
              },
              name: {
                color: "rgba(134, 157, 229, 1)",
                fontSize: 20,
                padding: [0, 0, 0, 150],
                fontWeight: "bold",
              },
            },
          },
          data: [
            {
              name: "男生",
              type: "max",
              symbol: "image://" + male,
            },
          ],
        },
      },
      {
        type: "bar",
        barWidth: 20,
        data: [1],
        barGap: "-100%",
        itemStyle: {
          normal: {
            barBorderRadius: 10,
            color: "#00FCFD",
          },
        },
        markPoint: {
          symbol: "rect",
          // x:'0%',
          symbolSize: [52, 122],
          symbolOffset: [35, 0],
          label: {
            color: "rgba(0,0,0,0)",
            formatter: (params) => {
              console.log("params", params);
              return `{value|${(femalePercent * 100).toFixed(
                2
              )}%}\n\n\n\n\n\n\n{name|${params.name}}`;
            },
            rich: {
              value: {
                color: "rgba(0, 252, 253, 1)",
                fontSize: 20,
                padding: [0, 160, 0, 0],
                fontWeight: "bold",
              },
              name: {
                color: "rgba(134, 157, 229, 1)",
                fontSize: 20,
                padding: [0, 160, 0, 40],
                fontWeight: "bold",
              },
            },
          },
          data: [
            {
              name: "女生",
              type: "max",
              symbol: "image://" + female,
            },
          ],
        },
      },
    ],
  };
  mycharts.setOption(option);
};
const initLine = () => {
  const mycharts = echarts.init(line.value);
  let option = {
    title: {
      text: "每月用户注册折线图",
      textStyle: {
        color: "#9ed0fb",
        fontSize: 20,
        fontFamily: "楷体",
      },
      left: "center",
    },
    backgroundColor: "#FFF",
    grid: {
      top: "5%",
      bottom: "5%",
      left: "6%",
      right: "4%",
    },
    tooltip: {
      trigger: "axis",
      label: {
        show: true,
      },
    },
    xAxis: {
      name: "时间",
      boundaryGap: true, //默认，坐标轴留白策略
      axisLine: {
        show: true,
        symbol: ["none", "arrow"],
      },
      splitLine: {
        show: true,
      },
      axisTick: {
        show: false,
        alignWithLabel: true,
      },
      data: lineData.value.xdata,
    },
    yAxis: {
      name: "数量",
      nameLocation: "middle",
      axisLine: {
        show: true,
        symbol: ["none", "arrow"],
      },
      splitLine: {
        show: true,
        lineStyle: {
          type: "dashed",
          color: "rgba(33,148,246,0.2)",
        },
      },
      axisTick: {
        show: false,
      },
      splitArea: {
        show: true,
        areaStyle: {
          color: "rgb(245,250,254)",
        },
      },
    },
    series: [
      {
        type: "line",
        symbol: "circle",
        symbolSize: 7,
        name: "注册数量",
        lineStyle: {
          color: "rgb(33,148,246)",
          shadowBlur: 12,
          shadowColor: "rgb(33,148,246,0.9)",
          shadowOffsetX: 1,
          shadowOffsetY: 1,
        },
        itemStyle: {
          color: "rgb(33,148,246)",
          borderWidth: 1,
          borderColor: "#FFF",
        },
        label: {
          show: false,
          distance: 1,
          emphasis: {
            show: false,
            rich: {
              bg: {
                width: 78,
                //height:42,
                color: "#FFF",
                padding: [20, 0, 20, 10],
              },
              br: {
                width: "100%",
                height: "100%",
              },
            },
          },
        },
        data: lineData.value.ydata,
      },
    ],
  };
  mycharts.setOption(option);
};
</script>

<style lang="scss" scoped>
.line {
  height: 400px;
  widows: 500px;
}
.container {
  height: 400px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  .charts {
    width: 600px;
    height: 400px;
  }
  .middle {
    width: 450px;
    height: 450px;
  }
  .right {
    width: 600px;
    height: 150px;
  }
}
.form {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
